package cn.com.geoway.booksystem.service;

import cn.com.geoway.booksystem.dao.BookBorrowDao;
import cn.com.geoway.booksystem.dao.BookDao;
import cn.com.geoway.booksystem.entity.Book;
import cn.com.geoway.booksystem.entity.Borrow;
import cn.com.geoway.booksystem.entity.User;
import net.sf.json.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("borrowService")
public class BorrowServiceImpl implements BorrowService {

    @Resource
    private BookBorrowDao bookBorrowDao;
    @Resource
    private BookDao bookDao;
    @Resource
    private BookService bookService;


    public Borrow repalce(Borrow curr,Borrow origin){

        if(curr.getUser()==null){
            curr.setUser(origin.getUser());
        }
        if(curr.getBook()==null){
            curr.setBook(origin.getBook());
        }
        if(curr.getType ()==null){
            curr.setType(origin.getType());
        }
        if(curr.getRecord ()==null){
            curr.setRecord(origin.getRecord());
        }

        if(curr.getBorrowDateTime()==null){
            curr.setBorrowDateTime(origin.getBorrowDateTime());
        }
        if(curr.getReturnDateTime()==null){
            curr.setReturnDateTime(origin.getReturnDateTime());
        }
        return curr;
    }


    //借阅审批
    @Override
    public JSONObject update(Integer borrowId,Integer record) {
      JSONObject result = new JSONObject();
      Borrow borrow = null;
      if (borrowId != null)
          borrow = bookBorrowDao.findId(borrowId);
          if (record == 1) {
              borrow.setRecord(record);
              bookBorrowDao.save(borrow);
              result.put("success", true);
              result.put("msg", "审批通过");
              return result;
          }
          if (record == 2) {
              borrow.setRecord(record);
              bookBorrowDao.save(borrow);
              //借书失败，图书数量加一
              Book book = borrow.getBook();
              book.setNum(book.getNum() + 1);
              bookDao.save(book);
              result.put("success", true);
              result.put("msg", "审批未通过");
              return result;
          } else {
              result.put("success", false);
              result.put("msg", "审批出错");
              return result;
          }
  }

  //归还图书
    @Transactional
    @Override
    public JSONObject returnbook(Integer borrowId) {
        JSONObject result = new JSONObject();
        Borrow borrow = null;
        if (borrowId != null) {
            borrow = bookBorrowDao.findId(borrowId);
            borrow.setType(2);
            borrow.setReturnDateTime(new Date());
            bookBorrowDao.save(borrow);
            Book book = borrow.getBook();
            book.setNum(book.getNum()+1);
            bookDao.save(book);
            result.put("success", true);
            result.put("msg", "还书成功");
            return result;
        } else {
            result.put("success", false);
            result.put("msg", "还书失败");
            return result;
        }
    }

    //借阅记录
    @Override
    public List<Borrow> list(Map<String,Object> map, Integer page, Integer pageSize){
        Pageable pageable = PageRequest.of(page, pageSize, Sort.Direction.DESC, "id");
        Page<Borrow> pages = bookBorrowDao.findAll(new Specification<Borrow>() {

            @Override
            public Predicate toPredicate(Root<Borrow> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate predicate = cb.conjunction();


               if (map.get("user") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("user"), map.get("user")));
                }
                if (map.get("record") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("record"), map.get("record")));
                }
                if (map.get("book") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("book"), map.get("book")));
                }
                if (map.get("username") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("username"), map.get("username")));
                }
                if (map.get("type") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("type"), map.get("type")));
                }
                return predicate;
            }
        }, pageable);
        return pages.getContent();
    }

    //个人借阅记录
    @Override
    public List<Borrow> list1(Map<String,Object> map, Integer page, Integer pageSize){
        Pageable pageable = PageRequest.of(page, pageSize, Sort.Direction.DESC, "id");
        Page<Borrow> pages = bookBorrowDao.findAll(new Specification<Borrow>() {

            @Override
            public Predicate toPredicate(Root<Borrow> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate predicate = cb.conjunction();


                if (map.get("user") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("user"), map.get("user")));
                }
                if (map.get("record") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("record"), map.get("record")));
                }
                predicate.getExpressions().add(cb.equal(root.get("username"), map.get("username")));
                return predicate;
            }
        }, pageable);
        return pages.getContent();
    }
    @Override
    public Long getTotal(Map<String, Object> map) {
        Long count=bookBorrowDao.count(new Specification<Borrow>() {
            @Override
            public Predicate toPredicate(Root<Borrow> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate predicate=cb.conjunction();

                // 加入 等于
                if (map.get("user") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("user"), map.get("user")));
                }
                if (map.get("record") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("record"), map.get("record")));
                }

                return predicate;
            }
        });
        return count;
    }
    @Override
    public Long getTotal1(Map<String, Object> map) {
        Long count=bookBorrowDao.count(new Specification<Borrow>() {
            @Override
            public Predicate toPredicate(Root<Borrow> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate predicate=cb.conjunction();

                // 加入 等于
                if (map.get("user") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("user"), map.get("user")));
                }
                if (map.get("record") != null) {
                    predicate.getExpressions().add(cb.equal(root.get("record"), map.get("record")));
                }
                predicate.getExpressions().add(cb.equal(root.get("username"), map.get("username")));
                return predicate;
            }
        });
        return count;
    }

    //借阅申请
    @Transactional
    @Override
    public Map<String, Object> borrow( String bookId,String username){
        Map<String, Object> map = new HashMap<String, Object>();
        Book book = bookDao.findId(Integer.parseInt(bookId));
        if (book.getNum() == 0){
            map.put("msg","此书库存不足,无法借阅");
            return map;
        }
        User currentUser =	(User) SecurityUtils.getSubject().getSession().getAttribute("currentUser");
        Borrow borrow = new Borrow();
        borrow.setBook(book);
        borrow.setBorrowDateTime(new Date());
        borrow.setUser(currentUser);
        borrow.setType(1);
        borrow.setRecord(0);
        borrow.setUsername(username);
        Borrow bor = bookBorrowDao.save(borrow);
        if(null != bor){
            book.setNum(book.getNum()-1);
            bookService.update(book);
            map.put("success",true);
            map.put("msg","借书成功");
            return map;
        }else{
            map.put("msg","借书失败");
            return map;
        }
    }

}
